using System;
using System.Data;

namespace Glpt.Data
{
    /// <summary>
    /// 过滤数据流类
    /// </summary>
    public class FilterDataReader : IDataReader
    {
        private IDataReader dtread = null;
        private int irowIndex = 0;
        private int itotal = 0;//总数
        private int iremainder = -1;//余数
        private int split_col_id = -1;//分片字段序号
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="read">数据流</param>
        /// <param name="remainder">余数</param>
        /// <param name="total">总数</param>
        /// <param name="split_colname">分片字段名</param>
        public FilterDataReader(IDataReader read, int remainder, int total, string split_colname)
        {
            dtread = read;
            iremainder = remainder;
            itotal = total;
            if (split_colname.Length > 0)
            {
                try
                {
                    split_col_id = dtread.GetOrdinal(split_colname);
                }
                catch
                {
                    throw new Exception(split_colname + "字段名不存在");
                }
            }
        }

        public bool Read()
        {
            bool hasdata = false;
            while (dtread.Read())
            {
                int split_value = 0;
                if (split_col_id >= 0)
                {
                    byte[] buf = DataFuns.DefaultEncoding.GetBytes(dtread[split_col_id].ToString());
                    for (int i = 0; i < buf.Length; i++)
                    {
                        split_value += buf[i];
                    }
                }
                else
                {
                    split_value = irowIndex++;
                }
                if (itotal > 1 && iremainder >= 0 && split_value % itotal != iremainder)
                    continue;
                else
                {
                    hasdata = true;
                    break;
                }
            }
            return hasdata;
        }

        /// <summary>
        /// 关闭StreamReader对象和基础流
        /// </summary>
        public void Close()
        {
            if (!dtread.IsClosed) dtread.Close();
        }

        public int FieldCount
        {
            get { return dtread.FieldCount; }
        }
        public string GetString(int i)
        {
            return dtread.GetString(i);
        }

        public object GetValue(int i)
        {
            return dtread.GetValue(i);
        }

        public string GetName(int i)
        {
            return dtread.GetName(i);
        }

        public int GetOrdinal(string name)
        {
            return dtread.GetOrdinal(name);
        }

        public int Depth
        {
            get
            {
                return dtread.Depth;
            }
        }

        public bool IsClosed
        {
            get
            {
                return dtread.IsClosed;
            }
        }

        public int RecordsAffected
        {
            get
            {
                return dtread.RecordsAffected;
            }
        }

        public DataTable GetSchemaTable()
        {
            return dtread.GetSchemaTable();
        }

        public bool NextResult()
        {
            return dtread.NextResult();
        }

        public object this[int i]
        {
            get
            {
                return dtread[i];
            }
        }
        public object this[string name]
        {
            get
            {
                return dtread[name];
            }
        }
        public bool GetBoolean(int i)
        {
            return dtread.GetBoolean(i);
        }
        public byte GetByte(int i)
        {
            return dtread.GetByte(i);
        }
        public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)
        {
            return dtread.GetBytes(i, fieldOffset, buffer, bufferoffset, length);
        }
        public char GetChar(int i)
        {
            return dtread.GetChar(i);
        }
        public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length)
        {
            return dtread.GetChars(i, fieldoffset, buffer, bufferoffset, length);
        }
        public IDataReader GetData(int i)
        {
            return dtread.GetData(i);
        }
        public string GetDataTypeName(int i)
        {
            return dtread.GetDataTypeName(i);
        }
        public DateTime GetDateTime(int i)
        {
            return dtread.GetDateTime(i);
        }
        public decimal GetDecimal(int i)
        {
            return dtread.GetDecimal(i);
        }
        public double GetDouble(int i)
        {
            return dtread.GetDouble(i);
        }
        public Type GetFieldType(int i)
        {
            return dtread.GetFieldType(i);
        }
        public float GetFloat(int i)
        {
            return dtread.GetFloat(i);
        }
        public Guid GetGuid(int i)
        {
            return dtread.GetGuid(i);
        }
        public short GetInt16(int i)
        {
            return dtread.GetInt16(i);
        }
        public int GetInt32(int i)
        {
            return dtread.GetInt32(i);
        }
        public long GetInt64(int i)
        {
            return dtread.GetInt64(i);
        }
        public int GetValues(object[] values)
        {
            return dtread.GetValues(values);
        }
        public bool IsDBNull(int i)
        {
            return dtread.IsDBNull(i);
        }
        public void Dispose()
        {
            try
            {
                GC.Collect();
            }
            catch { }
        }
        ~FilterDataReader()
        {
            Dispose();
        }
    }
}
